const { resolve } = require('path')
const { PROJECT_PATH, isDEV } = require('../constants')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin') // copy public 下的静态资源文件到 dist
const WebpackBar = require('webpackbar')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin') // build 构建 检查 ts 类型检测
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

// 抽离 cssLoaders
const getCssLoaders = (importLoaders, modules = false) => [
  isDEV ? 'style-loader' : MiniCssExtractPlugin.loader,
  {
    loader: 'css-loader',
    options: {
      // 是否开启模块化  默认为false
      modules,
      // sourceMap: isDev,
      importLoaders,
    },
  },
  {
    loader: 'postcss-loader',
    options: {
      postcssOptions: {
        plugins: [
          require('postcss-flexbugs-fixes'),
          isDEV && [
            'postcss-preset-env',
            {
              autoprefixer: {
                grid: true,
                flexbox: 'no-2009',
              },
              stage: 3,
            },
          ],
        ].filter(Boolean),
      },
    },
  },
]

module.exports = {
  entry: {
    index: resolve(PROJECT_PATH, './src/index.js'),
  },
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename],
    },
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        include: [resolve(PROJECT_PATH, './public/assets/styles')],
        use: getCssLoaders(1),
      },
      {
        test: /\.less$/,
        include: [resolve(PROJECT_PATH, './src/components')],
        use: [
          ...getCssLoaders(2, {
            mode: 'local',
            localIdentName: '[local]-[hash:base64:5]',
            exportLocalsConvention: 'camelCase', // 转为小驼峰
          }),
          {
            loader: 'less-loader',
            options: {},
          },
        ],
      },
      {
        test: /\.scss$/,
        include: [resolve(PROJECT_PATH, './src/components'), resolve(PROJECT_PATH, './src/pages')],
        use: [
          ...getCssLoaders(2, {
            mode: 'local',
            localIdentName: '[local]-[hash:base64:5]',
            exportLocalsConvention: 'camelCase', // 转为小驼峰
          }),
          {
            loader: 'sass-loader',
            options: {},
          },
        ],
      },
      {
        test: /\.css$/,
        include: [resolve(PROJECT_PATH, './node_modules')],
        use: getCssLoaders(2),
      },
      // 使用webpack5自带的 asset module 允许使用资源文件（字体，图标等）而无需配置额外的 loader。
      {
        test: /\.(jpe?g|png|gif)$/i,
        type: 'asset',
        generator: {
          // 输出文件位置以及文件名
          // [ext] 自带 "." 这个与 url-loader 配置不同
          filename: '[name][hash:8][ext]',
        },
        parser: {
          dataUrlCondition: {
            maxSize: 7 * 1024, //超过50kb不转 base64
          },
        },
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
        type: 'asset',
        generator: {
          // 输出文件位置以及文件名
          filename: '[name][hash:8][ext]',
        },
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 超过100kb不转 base64
          },
        },
      },
      {
        test: /\.(tsx?|jsx|js)$/,
        loader: 'babel-loader',
        options: { cacheDirectory: true },
        exclude: /node_modules/,
      },
    ],
  },
  resolve: {
    // 配置别名
    alias: {
      Assets: resolve(PROJECT_PATH, './public/assets'),
      Components: resolve(PROJECT_PATH, './src/components'),
      Utils: resolve(PROJECT_PATH, './src/utils'),
      Typings: resolve(PROJECT_PATH, './src/typings'),
    },
    extensions: ['.tsx', '.ts', '.js', '.json'], // 省略后缀名
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: resolve(PROJECT_PATH, './public/index.html'),
      filename: 'index.html',
      cache: false,
      minify: isDEV
        ? false
        : {
            removeAttributeQuotes: true,
            collapseWhitespace: true,
            removeComments: true,
            collapseBooleanAttributes: true,
            collapseInlineTagWhitespace: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            minifyCSS: true,
            minifyJS: true,
            minifyURLs: true,
            useShortDoctype: true,
          },
    }),
    // 把 public 下的静态资源文件给 打包到 dist 目录下
    new CopyPlugin({
      patterns: [
        {
          context: resolve(PROJECT_PATH, './public'),
          from: '*',
          to: resolve(PROJECT_PATH, './dist'),
          toType: 'dir',
          globOptions: {
            dot: true,
            gitignore: true,
            ignore: ['**/index.html'],
          },
        },
      ],
    }),
    new WebpackBar({
      name: isDEV ? '正在启动' : '正在打包',
      color: '#fa8c16',
    }),
    new ForkTsCheckerWebpackPlugin({
      typescript: {
        configFile: resolve(PROJECT_PATH, './tsconfig.json'),
      },
    }),
  ],
  // 排除 react 库 通过 cdn 页面引入
  // externals: {
  //   react: 'React',
  //   'react-dom': 'ReactDOM',
  // },
}
